﻿using Client.MirScenes;
using Client.MirScenes.Dialogs;
using System;
using System.Drawing;
using System.Linq;

public static class MirTool
{
    public static string ToStr(this Point point)
    {
        if(point==null)
        {
            return "该坐标无效";
        }
        return String.Format("({0},{1})",point.X,point.Y);
    }
    public static uint SumExperience = 0;
    public static uint SumKill = 0;

    public static bool FindAndChangeItem(string itemName)
    {
        UserItem amulet = GameScene.User.Equipment[(int)EquipmentSlot.Amulet];
        if (amulet == null || !amulet.Info.Name.Contains(itemName))
        {
            var myAmulet = GameScene.User.Inventory.Where(a => a != null && a.Name.Contains(itemName)).FirstOrDefault();
            if (myAmulet != null)
            {
                var cell = GameScene.Scene.InventoryDialog.GetCell(myAmulet.UniqueID);
                if (cell == null)
                    cell = GameScene.Scene.BeltDialog.GetCell(myAmulet.UniqueID);
                if (cell == null)
                    return false;
                cell.UseItem();
            }
        }
        return true;

    }
    private static StatType GetGemType(UserItem gem)
    {
        if ((gem.Info.MaxDC + gem.DC) > 0)
            return StatType.DC;

        else if ((gem.Info.MaxMC + gem.MC) > 0)
            return StatType.MC;

        else if ((gem.Info.MaxSC + gem.SC) > 0)
            return StatType.SC;

        else if ((gem.Info.MaxAC + gem.AC) > 0)
            return StatType.AC;

        else if ((gem.Info.MaxMAC + gem.MAC) > 0)
            return StatType.MAC;

        else if ((gem.Info.Durability) > 0)
            return StatType.Durability;

        else if ((gem.Info.AttackSpeed + gem.AttackSpeed) > 0)
            return StatType.ASpeed;

        else if ((gem.Info.Agility + gem.Agility) > 0)
            return StatType.Agility;

        else if ((gem.Info.Accuracy + gem.Accuracy) > 0)
            return StatType.Accuracy;

        else if ((gem.Info.PoisonAttack + gem.PoisonAttack) > 0)
            return StatType.PoisonAttack;

        else if ((gem.Info.Freezing + gem.Freezing) > 0)
            return StatType.Freezing;

        else if ((gem.Info.MagicResist + gem.MagicResist) > 0)
            return StatType.MagicResist;

        else if ((gem.Info.PoisonResist + gem.PoisonResist) > 0)
            return StatType.PoisonResist;

        else if ((gem.Info.Luck + gem.Luck) > 0)
            return StatType.Luck;

        else if ((gem.Info.PoisonRecovery + gem.PoisonRecovery) > 0)
            return StatType.PoisonRegen;

        else if ((gem.Info.HP + gem.HP) > 0)
            return StatType.HP;

        else if ((gem.Info.MP + gem.MP) > 0)
            return StatType.MP;

        else if ((gem.Info.HealthRecovery + gem.HealthRecovery) > 0)
            return StatType.HP_Regen;

        // These may be incomplete. Item definitions may be missing?

        else if ((gem.Info.HPrate) > 0)
            return StatType.HP_Percent;

        else if ((gem.Info.MPrate) > 0)
            return StatType.MP_Percent;

        else if ((gem.Info.SpellRecovery) > 0)
            return StatType.MP_Regen;

        else if ((gem.Info.Holy) > 0)
            return StatType.Holy;

        else if ((gem.Info.Strong + gem.Strong) > 0)
            return StatType.Strong;

        else if (gem.Info.HPrate > 0)
            return StatType.HP_Regen;

        else
            return StatType.Unknown;
    }
    public static int CalculateCombine(UserItem tempFrom, UserItem tempTo)
    {

        
        int successchance = tempFrom.Info.Reflect;

        // Gem is only affected by the stat applied.
        // Drop rate per gem won't work if gems add more than 1 stat, i.e. DC + 2 per gem.

            StatType GemType = GetGemType(tempFrom);

        switch (GemType)
        {
            case StatType.AC:
                successchance *= (int)tempTo.AC;
                break;

            case StatType.MAC:
                successchance *= (int)tempTo.MAC;
                break;

            case StatType.DC:
                successchance *= (int)tempTo.DC;
                break;

            case StatType.MC:
                successchance *= (int)tempTo.MC;
                break;

            case StatType.SC:
                successchance *= (int)tempTo.SC;
                break;

            case StatType.ASpeed:
                successchance *= (int)tempTo.AttackSpeed;
                break;

            case StatType.Accuracy:
                successchance *= (int)tempTo.Accuracy;
                break;

            case StatType.Agility:
                successchance *= (int)tempTo.Agility;
                break;

            case StatType.Freezing:
                successchance *= (int)tempTo.Freezing;
                break;

            case StatType.PoisonAttack:
                successchance *= (int)tempTo.PoisonAttack;
                break;

            case StatType.MagicResist:
                successchance *= (int)tempTo.MagicResist;
                break;

            case StatType.PoisonResist:
                successchance *= (int)tempTo.PoisonResist;
                break;

            // These attributes may not work as more than 1 stat is
            // added per gem, i.e + 40 HP.

            case StatType.HP:
                successchance *= (int)tempTo.HP;
                break;

            case StatType.MP:
                successchance *= (int)tempTo.MP;
                break;

            case StatType.HP_Regen:
                successchance *= (int)tempTo.HealthRecovery;
                break;

            // I don't know if this conflicts with benes.
            case StatType.Luck:
                successchance *= (int)tempTo.Luck;
                break;

            case StatType.Strong:
                successchance *= (int)tempTo.Strong;
                break;

            case StatType.PoisonRegen:
                successchance *= (int)tempTo.PoisonRecovery;
                break;


            /*
                 Currently not supported.
                 Missing item definitions.

                 case StatType.HP_Precent:
                 case StatType.MP_Precent:
                 case StatType.MP_Regen:
                 case StatType.Holy:
                 case StatType.Durability:


            */
            default:
                successchance *= (int)tempTo.GemCount;
                break;

        }

        successchance = successchance >= tempFrom.Info.CriticalRate ? 0 : (tempFrom.Info.CriticalRate - successchance);
        return successchance;
    }

    public static int CalculateRefine(RefineDialog refineDialog,UserItem targetItem)
    {
        //START OF FORMULA



        short OrePurity = 0;
        byte OreAmount = 0;
        byte ItemAmount = 0;
        short TotalDC = 0;
        short TotalMC = 0;
        short TotalSC = 0;
        short RequiredLevel = 0;
        short Durability = 0;
        short CurrentDura = 0;
        short AddedStats = 0;
        UserItem Ingredient;

        for (int i = 0; i < refineDialog.Grid.Length; i++)
        {
            Ingredient = refineDialog.Grid[i].Item;

            if (Ingredient == null) continue;
            if (Ingredient.Info.Type == ItemType.Weapon)
            {
                continue;
            }

            if ((Ingredient.Info.MaxDC > 0) || (Ingredient.Info.MaxMC > 0) || (Ingredient.Info.MaxSC > 0))
            {
                TotalDC += (short)(Ingredient.Info.MinDC + Ingredient.Info.MaxDC + Ingredient.DC);
                TotalMC += (short)(Ingredient.Info.MinMC + Ingredient.Info.MaxMC + Ingredient.MC);
                TotalSC += (short)(Ingredient.Info.MinSC + Ingredient.Info.MaxSC + Ingredient.SC);
                RequiredLevel += Ingredient.Info.RequiredAmount;
                if (Math.Round(Ingredient.MaxDura / 1000M) == Math.Round(Ingredient.Info.Durability / 1000M)) Durability++;
                if (Math.Round(Ingredient.CurrentDura / 1000M) == Math.Round(Ingredient.MaxDura / 1000M)) CurrentDura++;
                ItemAmount++;
            }

            if (Ingredient.Info.FriendlyName == "黑铁矿")
            {
                OrePurity += (short)Math.Round(Ingredient.CurrentDura / 1000M);
                OreAmount++;
            }
        }
        RefinedValue refinedValue = RefinedValue.None;
        byte refineAdded = 1;
        if (((TotalDC == 0) && (TotalMC == 0) && (TotalSC == 0)) || OreAmount == 0)
        {
            return 0;
        }

        short RefineStat = 0;

        if ((TotalDC > TotalMC) && (TotalDC > TotalSC))
        {
            refinedValue = RefinedValue.DC;
            RefineStat = TotalDC;
        }

        if ((TotalMC > TotalDC) && (TotalMC > TotalSC))
        {
            refinedValue = RefinedValue.MC;
            RefineStat = TotalMC;
        }

        if ((TotalSC > TotalDC) && (TotalSC > TotalMC))
        {
            refinedValue = RefinedValue.SC;
            RefineStat = TotalSC;
        }

        refineAdded = 1;


        int ItemSuccess = 0; //Chance out of 35%

        ItemSuccess += (RefineStat * 5) - targetItem.Info.RequiredAmount;
        ItemSuccess += 5;
        if (ItemSuccess > 10) ItemSuccess = 10;
        if (ItemSuccess < 0) ItemSuccess = 0; //10%


        if ((RequiredLevel / ItemAmount) > (targetItem.Info.RequiredAmount - 5)) ItemSuccess += 10; //20%
        if (Durability == ItemAmount) ItemSuccess += 10; //30%
        if (CurrentDura == ItemAmount) ItemSuccess += 5; //35%

        int OreSuccess = 0; //Chance out of 35%

        if (OreAmount >= ItemAmount) OreSuccess += 15; //15%
        if ((OrePurity / OreAmount) >= (RefineStat / ItemAmount)) OreSuccess += 15; //30%
        if (OrePurity == RefineStat) OreSuccess += 5; //35%

        int LuckSuccess = 0; //Chance out of 10%

        LuckSuccess = (targetItem.Luck + 5);
        if (LuckSuccess > 10) LuckSuccess = 10;
        if (LuckSuccess < 0) LuckSuccess = 0;


        int BaseSuccess =20; //20% as standard

        int SuccessChance = (ItemSuccess + OreSuccess + LuckSuccess + BaseSuccess);

        AddedStats = (byte)(targetItem.SC+targetItem.DC+targetItem.MC);
        if (targetItem.Info.Type == ItemType.Weapon) AddedStats = (short)(AddedStats * 6);
        else AddedStats = (short)(AddedStats *15);
        if (AddedStats > 50) AddedStats = 50;

        SuccessChance -= AddedStats;
        return SuccessChance;
    }

}

